<template>
  <n-space v-if="!isEdit" align="center" :wrap="false" class="show-or-edit">
    {{ value }}
    <icon-ant-design-form-outlined
      class="edit-icon"
      cursor-pointer
      @click="handleClick"
    />
  </n-space>
  <n-space v-else align="center" :wrap="false">
    <n-tooltip :show="inputStatus === 'error'">
      <template #trigger>
        <n-input
          ref="inputRef"
          v-model:value="inputValue"
          placeholder="请输入"
          :status="inputStatus"
          @blur="validate"
          @input="validate"
        />
      </template>
      {{ inputErrorText }}
    </n-tooltip>
    <icon-line-md-close cursor-pointer @click="handleCancel" />
    <icon-eos-icons-bubble-loading v-if="loading" cursor-not-allowed />
    <icon-line-md-confirm v-else cursor-pointer @click="handleConfirm" />
  </n-space>
</template>

<script lang="ts" setup>
import { isEmpty, isUndefined } from "@/utils";
import { useLoadingFunc } from "@/hooks";

interface Props {
  value: string;
  /** input框是否不能为空 */
  notEmpty?: boolean;
  validate?: (v: string) => boolean | Error;
  /** 返回值表示是否关闭编辑状态 */
  onUpdateValue?:
    | ((value: string) => Promise<boolean>)
    | ((value: string) => boolean);
}
interface Emits {
  /** 返回值表示是否关闭编辑状态 */
  (e: "update:value", v: string): Promise<boolean> | boolean;
}
const props = defineProps<Props>();
const emits = defineEmits<Emits>();

const isEdit = ref(false);
const inputRef = ref();
const inputValue = ref(props.value);
const inputStatus = ref<"success" | "error">("success");
const inputErrorText = ref("");

const handleClick = async () => {
  isEdit.value = true;
  await nextTick();
  inputRef.value.focus();
};

const validate = () => {
  if (props.notEmpty) {
    if (isEmpty(inputValue.value)) {
      inputStatus.value = "error";
      inputErrorText.value = "不能为空";
      return false;
    }
  }
  if (props.validate) {
    const result = props.validate(inputValue.value);
    if (result instanceof Error) {
      inputStatus.value = "error";
      inputErrorText.value = result.message;
      return false;
    }
    if (!result) {
      inputStatus.value = "error";
      inputErrorText.value = "验证失败";
      return false;
    }
  }

  inputStatus.value = "success";
  return true;
};

const handleCancel = () => {
  inputValue.value = props.value;
  inputStatus.value = "success";
  isEdit.value = false;
};

const confirmEmit = async () => {
  const status = await emits("update:value", inputValue.value);
  // 返回值为undefined，表示未订阅此emit，关闭
  if (isUndefined(status)) return true;
  return status;
};
const { loading, func: handleConfirm } = useLoadingFunc(async () => {
  if (!validate()) return;

  if (!props.onUpdateValue) {
    if (await confirmEmit()) {
      isEdit.value = false;
    }
    return;
  }
  const status = await props.onUpdateValue(inputValue.value);
  if (!status) return;
  isEdit.value = false;
});
</script>

<style scoped>
.edit-icon {
  display: none;
}
.show-or-edit:hover .edit-icon {
  display: block;
}
</style>
